﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ObjectRelationalMap.Models;
using ObjectRelationalMap.Interfaces;
using Caliburn.Micro;


namespace Presentation.ViewModels
{
    public class ListAnecdotesViewModel: PropertyChangedBase
    {
        ObjectRelationalMap.Interfaces.IReadWriteModels _modelsWriter;

        private Anecdote _newAnecdote;

        public class AnecdoteRow
        {
            private ActionHandler Handler { get; set; }

            public delegate void ActionHandler(Anecdote anecdote);

            public bool IsExisting { get; set; }

            public Anecdote Anecdote { get; set; }

            public AnecdoteRow(Anecdote anecdote, ActionHandler handler, bool isExisting)
            {
                Anecdote = anecdote;
                Handler = handler;
                IsExisting = isExisting;
            }

            public void HandleAction()
            {
                Handler(this.Anecdote);
            }
        }

        public BindableCollection<Domain> Domains
        {
            get
            {
                return new BindableCollection<Domain>(_modelsWriter.Domains); 
            }
        }

        public BindableCollection<Student> Students
        {
            get { return new BindableCollection<Student>(_modelsWriter.Students); }
        }

        public BindableCollection<AnecdoteRow> Anecdotes
        {
            get
            { 
                IOrderedEnumerable<Anecdote> sortedAnecdotes;
                sortedAnecdotes = _modelsWriter.Anecdotes.OrderBy<Anecdote, string>((a) => { return a.Student + a.Domain + a.Date.ToString(); });

                BindableCollection<AnecdoteRow> anecdoteRows = new BindableCollection<AnecdoteRow>();
                anecdoteRows.Add(new AnecdoteRow(new Anecdote(), AddAnecdote, false));
                foreach (Anecdote anecdote in sortedAnecdotes)
                {
                    anecdoteRows.Add(new AnecdoteRow(anecdote, RemoveAnecdote, true));
                }
                return anecdoteRows;
            }
        }

        public BindableCollection<string> UniqueNotes
        {
            get
            {
                BindableCollection<string> uniqueNotes = new BindableCollection<string>();
                foreach (Anecdote anecdote in _modelsWriter.Anecdotes)
                {
                    string note = anecdote.Note;
                    if (!uniqueNotes.Contains(note))
                    {
                        uniqueNotes.Add(note);
                    }
                }

                return uniqueNotes;
            }
        }

        public ListAnecdotesViewModel(IReadWriteModels models)
        {
            if (models == null)
            {
                models = new ORM(null);
            }

                _modelsWriter = models;
                _modelsWriter = models;

                _newAnecdote = new Anecdote();

                _modelsWriter.AnecdotesChanged += Refresh;
        }

        public bool CanAddAnecdote(Anecdote a)
        {
            return (a.Note != "" && a.Domain != "" && a.Student != "");
        }

        public void AddAnecdote(Anecdote anecdote)
        {
            if (CanAddAnecdote(anecdote))
            {
                Student anecdoteStudent = _modelsWriter.Students.GetByName(anecdote.Student);
                if (anecdoteStudent == null)
                {
                    anecdoteStudent = new Student() { Name = anecdote.Student };
                    _modelsWriter.Students.Add(anecdoteStudent);
                }

                Domain anecdoteDomain = _modelsWriter.Domains.GetByName(anecdote.Domain);
                if (anecdoteDomain == null)
                {
                    anecdoteDomain = new Domain() { Name = anecdote.Domain };
                    _modelsWriter.Domains.Add(anecdoteDomain);
                }

                _modelsWriter.Anecdotes.Add(anecdote);

                Refresh();
            }
        }

        public void RemoveAnecdote(Anecdote a)
        {
            _modelsWriter.Anecdotes.Remove(a);
            Refresh();
        }

        public void Refresh(object sender, EventArgs e)
        {
            //NotifyOfPropertyChange(() => UniqueNotes);
            //NotifyOfPropertyChange(() => Domains);
            //NotifyOfPropertyChange(() => Students);
            //NotifyOfPropertyChange(() => Anecdotes);
            Refresh();
        }
    }
}